
#ifndef	PHYSICS_HPP
#define	PHYSICS_HPP

#include <Box2D/Box2D.h>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <utils/from_string.hpp>

typedef	boost::shared_ptr< b2World > world_ptr;
typedef boost::weak_ptr< b2World > world_weak_ptr;

typedef boost::shared_ptr< b2Body > body_ptr;
typedef boost::weak_ptr< b2Body > body_weak_ptr;

typedef boost::shared_ptr< b2Joint > joint_ptr;
typedef boost::weak_ptr< b2Joint > joint_weak_ptr;

float32 const g_scale_b2_position = 10.0f;
float32 const g_inv_scale_b2_position = 1.0f / g_scale_b2_position;

body_ptr create_body( world_ptr world, b2BodyDef const * const definition );
joint_ptr create_joint( world_ptr world, b2JointDef const * const definition );

template < typename TJoint >
boost::shared_ptr< TJoint > create_joint( world_ptr world, b2JointDef const * const definition )
{
	return boost::shared_dynamic_cast< TJoint, b2Joint >( create_joint( world, definition ) );
};

inline float32 b2RadToDeg( float32 radians )
{
	return radians * ( 180.0f / b2_pi );
}

inline float32 b2DegToRad( float32 degrees )
{
	return degrees * ( b2_pi / 180.0f );
}

inline float32 b2Sign( float32 val )
{
	return val < 0.0f	? -1.0f
						: val > 0.0f	? 1.0f
										: 0.0f;
}

class contact_listener : public b2ContactListener
{
	void BeginContact( b2Contact * contact );
};

#define PHYSICS_DEBUG 1
#if PHYSICS_DEBUG

class debug_draw : public b2DebugDraw
{
public:
	debug_draw( );

	void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
	void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
	void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color);
	void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color);
	void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color);
	void DrawTransform(const b2Transform& xf);
    void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color);
    void DrawString(int x, int y, const char* string, ...); 
    void DrawAABB(b2AABB* aabb, const b2Color& color);
};

#endif

#endif	//PHYSICS_HPP
